package core.inputoutput.converters;

import java.util.Observable;

import core.inputoutput.formatting.Format;
/**
 * This is the abstract model used to create a "converter" which, based on a format, is capable of taking the data from 
 * whatever <T> is and transforming it into a readable PDF
 * @author Julian
 *
 * @param <T>
 */
public abstract class FormatConverter<T> extends Observable{

	@Override
	public void notifyObservers(Object arg) {
		this.setChanged();
		super.notifyObservers(arg);
	}


	protected static String NL = System.getProperty("line.separator");
	protected Format myFormat;
	
	public FormatConverter(Format f){
		myFormat = f;
	}
	
	
	/**
	 * Create an entry line in the output PDB string based on the format and info put in. Will progress
	 * linearly through each
	 * @param f
	 * @param atomInfo
	 * @return
	 */
	protected Object createEntry(Format f, String ... atomInfo) {
		String entry = "";
		for (int i = 0; i < f.getColumnWidths().length; i++){
			entry += formatInfo(f.getColumnWidths()[i], atomInfo[i]);
		}
		return entry + NL;
	}

	/**
	 * Returns a formatted string with spaces added to fill out the column width indicated.
	 * Spaces are added to the left side of the string.
	 * @param width
	 * @param string
	 * @return
	 */
	protected String formatInfo(int width, String string) {
		if (string == null) string = "";
		else if (string.length() > width)
			return string.substring(string.length()-width);
		width-=string.length();
		while (width > 0){
			string = " " + string;
			width--;
		}
		
		return string;
	}
	
	/**
	 * Trims a double to the appropriate size accoring to the PDB format (XXXXX.DDD) = three decimal places
	 * @param string
	 * @return
	 */
	protected String trimDoubleToSize(String string) {
		string += "000";
		return string.substring(0, string.indexOf(".")+4);
	}
	
	
	/**
	 * Apply this converter with the input format 
	 * @param data
	 * @return String corresponding to the PDB file resulting from the input format
	 */
	public abstract String applyConverter(T data);

	
	
}
